<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import { Search, Sunny, Moon } from '@element-plus/icons-vue'
//数据
interface TableItem {
  id: string
  date: string
  name: string
  state: string
  city: string
  address: string
  zip: string
  tag: 'Home' | 'Office'
}
const queryInput = ref('')
const tableData = ref<TableItem[]>([
  {
    id: '1',
    date: '2016-05-03',
    name: 'Jones',
    state: 'California',
    city: 'Los Angeles',
    address: 'No. 189, Grove St, Los Angeles',
    zip: 'CA 90036',
    tag: 'Home',
  },
  {
    id: '2',
    date: '2016-05-02',
    name: 'Jenkins',
    state: 'California',
    city: 'Los Angeles',
    address: 'No. 189, Grove St, Los Angeles',
    zip: 'CA 90036',
    tag: 'Office',
  },
  {
    id: '3',
    date: '2016-05-04',
    name: 'Tom',
    state: 'California',
    city: 'Los Angeles',
    address: 'No. 189, Grove St, Los Angeles',
    zip: 'CA 90036',
    tag: 'Home',
  },
  {
    id: '4',
    date: '2016-05-01',
    name: 'Lee',
    state: 'California',
    city: 'Los Angeles',
    address: 'No. 189, Grove St, Los Angeles',
    zip: 'CA 90036',
    tag: 'Office',
  },
  {
    id: '5',
    date: '2016-05-01',
    name: 'Wang',
    state: 'California',
    city: 'Los Angeles',
    address: 'No. 189, Grove St, Los Angeles',
    zip: 'CA 90036',
    tag: 'Office',
  },
  {
    id: '6',
    date: '2016-05-01',
    name: 'Smith',
    state: 'California',
    city: 'Los Angeles',
    address: 'No. 189, Grove St, Los Angeles',
    zip: 'CA 90036',
    tag: 'Office',
  },
  {
    id: '7',
    date: '2016-05-01',
    name: 'Doe',
    state: 'California',
    city: 'Los Angeles',
    address: 'No. 189, Grove St, Los Angeles',
    zip: 'CA 90036',
    tag: 'Office',
  },
  {
    id: '8',
    date: '2016-05-01',
    name: 'Gray',
    state: 'California',
    city: 'Los Angeles',
    address: 'No. 189, Grove St, Los Angeles',
    zip: 'CA 90036',
    tag: 'Office',
  },
  {
    id: '9',
    date: '2016-05-01',
    name: 'Lopez',
    state: 'California',
    city: 'Los Angeles',
    address: 'No. 189, Grove St, Los Angeles',
    zip: 'CA 90036',
    tag: 'Office',
  },
  {
    id: '10',
    date: '2016-05-01',
    name: 'William',
    state: 'California',
    city: 'Los Angeles',
    address: 'No. 189, Grove St, Los Angeles',
    zip: 'CA 90036',
    tag: 'Office',
  },
  {
    id: '11',
    date: '2016-05-01',
    name: 'King',
    state: 'California',
    city: 'Los Angeles',
    address: 'No. 189, Grove St, Los Angeles',
    zip: 'CA 90036',
    tag: 'Office',
  },
])
const originalTableData = ref([...tableData.value]) // 用于存储原始数据以便查询后恢复
const multipleTableRef = ref()
const selectedRows = ref<TableItem[]>([])

const dialogFormVisible = ref(false)
const formLabelWidth = '80px'
const dialogType = ref('add') // 用于区分新增或编辑
// 删除相关
const showDeleteDialog = ref(false)
const deleteType = ref<'row' | 'batch' | null>(null)
const deleteIndex = ref<number | null>(null)
// 方法
const handleSelectionChange = (val: TableItem[]) => {
  selectedRows.value = val
}
const filterTag = (value: string, row: TableItem) => {
  return row.tag === value
}
const handleAdd = () => {
  dialogFormVisible.value = true
  // 清空表单
  form.value = {
    id: '',
    date: '',
    name: '',
    state: '',
    city: '',
    address: '',
    zip: '',
    tag: 'Home',
  }
  dialogType.value = 'add' // 设置为新增模式
}
const handleEdit = (row: TableItem) => {
  dialogFormVisible.value = true
  dialogType.value = 'edit'
  // 直接使用行数据进行深拷贝
  form.value = { ...row } // row 包含完整的行数据
}
const handleDelRow = (row: TableItem) => {
  deleteType.value = 'row'
  // 通过ID查找在排序后数据中的位置
  const index = tableData.value.findIndex((item) => item.id === row.id)
  deleteIndex.value = index
  showDeleteDialog.value = true
}
const handleDel = () => {
  if (multipleTableRef.value.length === 0) {
    alert('请至少选择一条数据')
    return
  }
  deleteType.value = 'batch'
  showDeleteDialog.value = true
}
const confirmDelete = () => {
  if (deleteType.value === 'row' && deleteIndex.value !== null) {
    const delId = tableData.value[deleteIndex.value].id
    tableData.value.splice(deleteIndex.value, 1)
    const originalIndex = originalTableData.value.findIndex((item) => item.id === delId)
    if (originalIndex !== -1) {
      originalTableData.value.splice(originalIndex, 1)
    }
    showDeleteDialog.value = false
    deleteType.value = null
    deleteIndex.value = null
    return
  }
  if (deleteType.value === 'batch') {
    const idsToDelete = selectedRows.value.map((item) => item.id)
    if (idsToDelete.length > 0) {
      tableData.value = tableData.value.filter((item) => !idsToDelete.includes(item.id))
      originalTableData.value = originalTableData.value.filter(
        (item) => !idsToDelete.includes(item.id),
      )
      selectedRows.value = [] // 清空选中项
    }
    showDeleteDialog.value = false
    deleteType.value = null
    deleteIndex.value = null
    return
  }
  // 兜底关闭弹窗
  showDeleteDialog.value = false
  deleteType.value = null
  deleteIndex.value = null
}
const cancelDelete = () => {
  showDeleteDialog.value = false
  deleteType.value = null
  deleteIndex.value = null
}
const form = ref<TableItem>({
  id: '',
  date: '',
  name: '',
  state: '',
  city: '',
  address: '',
  zip: '',
  tag: 'Home',
})
const handleQueryInfo = () => {
  // 模拟查询逻辑，忽略大小写
  const query = queryInput.value.trim().toLowerCase()
  tableData.value = originalTableData.value.filter((item) =>
    item.name.toLowerCase().includes(query),
  )
  // 清空查询输入后回复表格数据
  if (query === '') {
    tableData.value = [...originalTableData.value] // 如果查询输入为空，恢复原始数据
    return
  }
}
const dialogConfirm = () => {
  if (dialogType.value === 'add') {
    // 新增逻辑
    const newId = String(Date.now())
    const newRow = { ...form.value, id: newId }
    tableData.value.push(newRow)
    originalTableData.value.push(newRow)
  } else {
    // 编辑逻辑，按唯一id查找并更新
    const index = tableData.value.findIndex((item) => item.id === form.value.id)
    if (index !== -1) {
      tableData.value[index] = { ...form.value }
    }
    const originalIndex = originalTableData.value.findIndex((item) => item.id === form.value.id)
    if (originalIndex !== -1) {
      originalTableData.value[originalIndex] = { ...form.value }
    }
  }
  dialogFormVisible.value = false
}
const handleSortChange = (sort: { prop: string; order: string }) => {
  // 多列综合排序：先按 date 排序，再按 name 排序
  if (sort.prop === 'date' || sort.prop === 'name') {
    tableData.value = [...tableData.value].sort((a, b) => {
      // 先按 date 排序
      if (a.date !== b.date) {
        return sort.order === 'descending'
          ? b.date.localeCompare(a.date)
          : a.date.localeCompare(b.date)
      }
      // date 相同再按 name 排序
      return a.name.localeCompare(b.name)
    })
  }
}

const pageSize = ref(5)
const currentPage = ref(1)

const handleSizeChange = (val: number) => {
  pageSize.value = val
}
const handleCurrentChange = (val: number) => {
  currentPage.value = val
}
// 分页数据计算属性
const paginatedData = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return tableData.value.slice(start, end)
})

const themeMode = ref<'light' | 'dark'>('dark')
const toggleTheme = (val: 'light' | 'dark') => {
  themeMode.value = val
}
watch(themeMode, (val) => {
  const html = document.documentElement
  const body = document.body
  if (val === 'dark') {
    html.classList.add('dark')
    body.classList.add('dark')
  } else {
    html.classList.remove('dark')
    body.classList.remove('dark')
  }
})
</script>

<template>
  <div class="table-box">
    <!-- 标题 -->
    <h2>Easy Vue3</h2>

    <!-- 查询 -->
    <div class="query-box">
      <el-input
        clearable
        :prefix-icon="Search"
        placeholder="请输入内容"
        v-model="queryInput"
        class="query-input"
        @input="handleQueryInfo"
      />
      <div class="button-right">
        <el-button type="primary" @click="handleAdd"> <i-ep-plus /> 新增 </el-button>
        <el-button type="danger" @click="handleDel"> <i-ep-delete /> 删除 </el-button>
      </div>
    </div>
    <!-- 表格 -->

    <el-table
      ref="multipleTableRef"
      :data="paginatedData"
      :default-sort="{ prop: 'date', order: 'descending' }"
      style="width: 100%"
      @selection-change="handleSelectionChange"
      @sort-change="handleSortChange"
    >
      <el-table-column type="selection" width="55" />
      <el-table-column prop="date" label="Date" sortable width="150" />
      <el-table-column prop="name" label="Name" sortable width="120" />
      <el-table-column prop="state" label="State" width="120" />
      <el-table-column
        prop="tag"
        label="Tag"
        width="100"
        :filters="[
          { text: 'Home', value: 'Home' },
          { text: 'Office', value: 'Office' },
        ]"
        :filter-method="filterTag"
        filter-placement="bottom-end"
      >
        <template #default="scope">
          <el-tag :type="scope.row.tag === 'Home' ? 'warning' : 'success'" disable-transitions>{{
            scope.row.tag
          }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="city" label="City" width="120" />
      <el-table-column prop="address" label="Address" width="400" />
      <el-table-column prop="zip" label="Zip" width="120" />
      <el-table-column fixed="right" label="Operations" width="120">
        <template #default="scope">
          <el-button link type="danger" size="small" @click.prevent="handleDelRow(scope.row)"
            >删除</el-button
          >
          <el-button link type="primary" size="small" @click.prevent="handleEdit(scope.row)"
            >编辑</el-button
          >
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      v-model:current-page="currentPage"
      v-model:page-size="pageSize"
      :page-sizes="[5, 10, 20, 50, 100]"
      background
      layout="total, sizes, prev, pager, next, jumper"
      :total="tableData.length"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />

    <!-- 弹出框 -->
    <el-dialog
      v-model="dialogFormVisible"
      :title="dialogType === 'add' ? '新增' : '编辑'"
      width="500"
    >
      <el-form :model="form">
        <el-form-item label="Date" :label-width="formLabelWidth">
          <el-input v-model="form.date" autocomplete="off" />
        </el-form-item>
        <el-form-item label="姓名" :label-width="formLabelWidth">
          <el-input v-model="form.name" autocomplete="off" />
        </el-form-item>
        <el-form-item label="State" :label-width="formLabelWidth">
          <el-input v-model="form.state" autocomplete="off" />
        </el-form-item>
        <el-form-item label="City" :label-width="formLabelWidth">
          <el-select v-model="form.city" placeholder="Please select a city">
            <el-option label="Shanghai" value="shanghai" />
            <el-option label="Beijing" value="beijing" />
          </el-select>
        </el-form-item>
        <el-form-item label="Address" :label-width="formLabelWidth">
          <el-input v-model="form.address" autocomplete="off" />
        </el-form-item>
        <el-form-item label="Zip" :label-width="formLabelWidth">
          <el-input v-model="form.zip" autocomplete="off" />
        </el-form-item>
        <el-form-item label="Tag" :label-width="formLabelWidth">
          <el-select v-model="form.tag" placeholder="Please select a tag">
            <el-option label="Home" value="Home" />
            <el-option label="Office" value="Office" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取消</el-button>
          <el-button type="primary" @click="dialogConfirm"> 确认 </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 删除确认弹窗 -->
    <el-dialog title="确认删除" v-model="showDeleteDialog" width="400">
      <span>确定要删除选中的数据吗？</span>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancelDelete">取消</el-button>
          <el-button type="primary" @click="confirmDelete">确认</el-button>
        </div>
      </template>
    </el-dialog>

    <div style="position: absolute; top: 20px; right: 40px; z-index: 10">
      <el-switch
        inline-prompt
        class="mt-2"
        style="margin-left: 24px"
        v-model="themeMode"
        :active-value="'dark'"
        :inactive-value="'light'"
        :active-icon="Moon"
        :inactive-icon="Sunny"
        active-text="暗色模式"
        inactive-text="亮色模式"
        @change="toggleTheme"
      />
    </div>
  </div>
</template>

<style type="scss" scoped>
.table-box {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;

  h2 {
    text-align: center;
    margin-bottom: 20px;
  }

  .el-pagination {
    margin: 20px 0;
  }

  .query-box {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;

    .query-input {
      width: 300px;
    }

    .el-button {
      margin-left: 10px;
    }
  }
}

.el-button svg {
  width: 1em;
  height: 1em;
  vertical-align: middle;
  margin-right: 4px;
  fill: currentColor;
}
</style>
